﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ProjApi;
using ESCoordinateConvert;
using System.IO;

namespace 坐标转换
{
    public delegate bool MyDelegate(string s, string a, string d, ProgressClass pbc);
    public delegate void ShowProgressDelegate(int totalStep, int currentStep);
    public delegate void ImportDataDelegate(string wkt);
    public partial class Form1 : Form
    {
        bool done = true;
        private List<string> domlist = new List<string>();
        public Form1()
        {
            InitializeComponent();
            helpProvider1.HelpNamespace = Application.StartupPath + "\\分辨率计算工具使用说明.chm";
            helpProvider1.SetShowHelp(this, true);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string wkt = GetWkt();
            if (wkt == "")
            {
                MessageBox.Show("请设置文件投影信息");
                return;
            }
            if (!checkBox1.Checked)
            {
                if (!File.Exists(textBox1.Text))
                    return;
                if (File.Exists(textBox1.Text + ".ovr"))
                    File.Move(textBox1.Text + ".ovr", textBox1.Text + "esearth.ovr");
                using (SaveFileDialog sf = new SaveFileDialog())
                {
                    if (Path.GetExtension(textBox1.Text).ToLower() == ".tif")
                    {
                        sf.Filter = "影像|*.tif";
                        if (sf.ShowDialog() == DialogResult.OK)
                        {
                            done = false;
                            MyDelegate del = new MyDelegate(GdalTransform.TransformTiff);
                            del.BeginInvoke(textBox1.Text, sf.FileName, wkt, new ProgressClass(progressBar1), null, null);
                        }
                    }
                    else if (Path.GetExtension(textBox1.Text).ToLower() == ".asc")
                    {
                        sf.Filter = "高程|*.asc";
                        if (sf.ShowDialog() == DialogResult.OK)
                        {
                            done = false;
                            MyDelegate del = new MyDelegate(GdalTransform.TransformAsc);
                            del.BeginInvoke(textBox1.Text, sf.FileName, wkt, new ProgressClass(progressBar1), null, null);
                        }
                    }
                }
            }
            else
            {
                MessageBox.Show("预处理后的影像默认存放在程序目录的tmp文件夹下");
                done = false;
                ImportDataDelegate importdom = new ImportDataDelegate(ImprotDomData);
                importdom.BeginInvoke(wkt, null, null);
            }
        }

        void ImprotDomData(string wkt)
        {
            int count = domlist.Count;
            ShowProgressDelegate showprogressdelegate = new ShowProgressDelegate(showProgress);
            string folder = Application.StartupPath + "\\tmp";
            for (int i = 0; i < domlist.Count; i++)
            {
                string desfilepath = Path.Combine(folder, Path.GetFileName(domlist[i]));
                if (!GdalTransform.TransformTiff(domlist[i], desfilepath, wkt, null))
                {
                    if (DialogResult.No == MessageBox.Show(Path.GetFileName(domlist[i]) + "预处理出错，是否继续导入其他数据？", "提示", MessageBoxButtons.YesNo))
                    {
                        showprogressdelegate(count, count);
                        return;
                    }
                    else
                    {
                        showprogressdelegate(count, i + 1);
                        continue;
                    }
                }
                else
                {
                    showprogressdelegate(count, i + 1);
                }
            }
        }

        void showProgress(int totalStep, int currentStep)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new ShowProgressDelegate(showProgress), totalStep, currentStep);
            }
            else
            {
                progressBar1.Maximum = totalStep;
                progressBar1.Value = currentStep;
                if (totalStep == currentStep)
                {
                    done = true;
                    MessageBox.Show("导入完成！", "提示");
                }
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            if (!File.Exists(textBox1.Text))
                return;
            string wkt = GetWkt();
            if (wkt == "")
            {
                MessageBox.Show("请设置文件投影信息");
                return;
            }
            button3.Enabled = false;
            button2.Enabled = false;
            ImportDataDelegate calc = new ImportDataDelegate(CalcResolution);
            calc.BeginInvoke(wkt, null, null);

        }

        void CalcResolution(string wkt)
        {
            string res = ((decimal)GdalTransform.GetLonLatResolution(textBox1.Text, wkt)).ToString();
            textBox2.Invoke(new MethodInvoker(delegate()
            {
                textBox2.Text = res;
                button3.Enabled = true;
                button2.Enabled = true;
            }));
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (!checkBox1.Checked)
            {
                using (OpenFileDialog op = new OpenFileDialog())
                {
                    op.Filter = "影像、高程文件|*.tif;*.asc";
                    if (op.ShowDialog() == DialogResult.OK)
                    {
                        textBox1.Text = op.FileName;
                    }
                }
            }
            else
            {
                using (FolderBrowserDialog fb = new FolderBrowserDialog())
                {
                    if (fb.ShowDialog() == DialogResult.OK)
                    {
                        string folder = fb.SelectedPath;
                        textBox1.Text = folder;
                        string[] tifs = Directory.GetFiles(folder, "*.tif");
                        for (int i = 0; i < tifs.Length; i++)
                        {
                            domlist.Add(tifs[i]);
                        }
                    }
                }
            }
        }

        private string GetWkt()
        {
            string wkt = "";
            CoordType coordType = CoordType.None;
            switch (cbEarth.Text)
            {
                case "北京1954":
                    coordType = CoordType.Beijing54;
                    break;
                case "西安1980":
                    coordType = CoordType.Xian80;
                    break;
                case "国家2000":
                    coordType = CoordType.CGCS2000;
                    break;
                case "WGS1984":
                    coordType = CoordType.WGS84;
                    break;
            }
            if (cbProject.Text == "经纬度")
            {
                wkt = GdalTransform.GetGCSWkt(coordType);
            }
            else if (cbProject.Text == "高斯3度")
            {
                if (!chkManual.Checked)
                    wkt = GdalTransform.GetWktByZone(coordType, ProjectionType.GAUSS_KRUGER, 3.0, int.Parse(tbDaihao.Text), chkDaihao.Checked);
                else
                    //wkt = GdalTransform.GetWktByCustom(coordType, ProjectionType.GAUSS_KRUGER, 3.0, int.Parse(tbZiwuxian.Text), double.Parse(tbLat.Text), double.Parse(tbPianyi.Text));
                    wkt = GdalTransform.GetWktByCustom(coordType, ProjectionType.GAUSS_KRUGER, 3.0, double.Parse(tbZiwuxian.Text), double.Parse(tbLat.Text), double.Parse(tbPianyi.Text));
            }
            else if (cbProject.Text == "高斯6度")
            {
                if (!chkManual.Checked)
                    wkt = GdalTransform.GetWktByZone(coordType, ProjectionType.GAUSS_KRUGER, 6.0, int.Parse(tbDaihao.Text), chkDaihao.Checked);
                else
                    wkt = GdalTransform.GetWktByCustom(coordType, ProjectionType.GAUSS_KRUGER, 6.0, int.Parse(tbZiwuxian.Text), double.Parse(tbLat.Text), double.Parse(tbPianyi.Text));
            }
            else if (cbProject.Text == "UTM")
            {
                if (!chkManual.Checked)
                    wkt = GdalTransform.GetWktByZone(coordType, ProjectionType.UTM, 6.0, int.Parse(tbDaihao.Text), chkDaihao.Checked);
                else
                    wkt = GdalTransform.GetWktByCustom(coordType, ProjectionType.UTM, 6.0, int.Parse(tbZiwuxian.Text), double.Parse(tbLat.Text), double.Parse(tbPianyi.Text));
            }
            else if (cbProject.Text == "墨卡托")
            {
                if (!chkManual.Checked)
                    wkt = GdalTransform.GetWktByZone(coordType, ProjectionType.MERCATOR, 6.0, int.Parse(tbDaihao.Text), chkDaihao.Checked);
                else
                    wkt = GdalTransform.GetWktByCustom(coordType, ProjectionType.MERCATOR, 6.0, int.Parse(tbZiwuxian.Text), double.Parse(tbLat.Text), double.Parse(tbPianyi.Text));
            }
            return wkt;
        }

        private void Form1_HelpButtonClicked(object sender, CancelEventArgs e)
        {
            if (!File.Exists(helpProvider1.HelpNamespace))
            {
                return;                
            }
            System.Diagnostics.Process.Start(helpProvider1.HelpNamespace);
            e.Cancel = true;
        }

        private void chkManual_CheckedChanged(object sender, EventArgs e)
        {
            if (chkManual.Checked)
            {
                tbZiwuxian.ReadOnly = false;
                tbPianyi.ReadOnly = false;
                tbLat.ReadOnly = false;
            }
            else
            {
                tbZiwuxian.ReadOnly = true;
                tbPianyi.ReadOnly = true;
                tbLat.ReadOnly = true;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!done)
            {
                if (MessageBox.Show("正在预处理数据，确定要退出？", "提示", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    e.Cancel = true;
                }
            }
        }
    }
}
